﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using RaytracerLib;
using System.ComponentModel;
using RaytracerLib.Samplers;
using RaytracerLib.Resamplers;
using RaytracerLib.Postprocessing.LightCorrector;

namespace Raytracer.PropertyGridDecorators
{
    public class FilmProperties
    {
        private Film m_film;

        public FilmProperties(Film a_film)
        {
            m_film = a_film;
        }

        [Category(Categories.SIZE)]
        public int Width
        {
            get
            {
                return m_film.Width;
            }
            set
            {
                m_film.Width = value;
            }
        }

        [Category(Categories.SIZE)]
        public int Height
        {
            get
            {
                return m_film.Height;
            }
            set
            {
                m_film.Height = value;
            }
        }

        [Category(Categories.RESAMPLING)]
        [TypeConverter(typeof(ResamplerConverter))]
        public ResamplerProperties Resampler
        {
            get
            {
                if (m_film.Resampler is LocalGridResampler)
                    return new LocalGridResamplerProperties(m_film.Resampler as LocalGridResampler);
                else if (m_film.Resampler is NetResizerResampler)
                    return new NetResizerResamplerProperties(m_film.Resampler as NetResizerResampler);
                else
                    return new FilterResamplerProperties(m_film.Resampler as FilterResampler);
            }
        }

        [DisplayName("Resampler type")]
        [Category(Categories.RESAMPLING)]
        public RaytracerLib.Resamplers.ResamplerType ResamplerType
        {
            get
            {
                return m_film.Resampler.ResamplerType;
            }
            set
            {
                var old = m_film.Resampler;
                m_film.Resampler = RaytracerLib.Resamplers.Resampler.Create(value);

                if ((old is NetResizerResampler) && (m_film.Resampler is NetResizerResampler))
                {
                    (m_film.Resampler as NetResizerResampler).InterpolationMode =
                        (old as NetResizerResampler).InterpolationMode;
                }
                else if ((old is FilterResampler) && (m_film.Resampler is FilterResampler))
                {
                    (m_film.Resampler as FilterResampler).Filter = 
                        (old as FilterResampler).Filter;
                }
            }
        }

        [DisplayName("Sampler type")]
        [Category(Categories.SAMPLING)]
        public SamplerType SamplerType
        {
            get
            {
                return m_film.Sampler.SamplerType;
            }
            set
            {
                int subres = -1;

                if (m_film.Sampler is UniformSampler)
                    subres = (m_film.Sampler as UniformSampler).Subresolution;
                else if (m_film.Sampler is LowDiscrepancySequenceSampler)
                    subres = (m_film.Sampler as LowDiscrepancySequenceSampler).Subresolution;

                m_film.Sampler = RaytracerLib.Samplers.Sampler.Create(value);

                if (subres != -1)
                {
                    if (m_film.Sampler is UniformSampler)
                        (m_film.Sampler as UniformSampler).Subresolution = subres;
                    else if (m_film.Sampler is LowDiscrepancySequenceSampler)
                        (m_film.Sampler as LowDiscrepancySequenceSampler).Subresolution = subres;
                }
            }
        }

        [Category(Categories.SAMPLING)]
        [TypeConverter(typeof(SamplerConverter))]
        public SamplerProperties Sampler
        {
            get
            {
                if (m_film.Sampler is UniformSampler)
                    return new UniformSamplerProperties(m_film.Sampler as UniformSampler);
                else if (m_film.Sampler is PoissonSampler)
                    return new PoissonSamplerProperties(m_film.Sampler as PoissonSampler);
                else if (m_film.Sampler is HaltonFoldedSampler)
                    return new HaltonFoldedSamplerProperties(m_film.Sampler as HaltonFoldedSampler);
                else if (m_film.Sampler is HaltonSampler)
                    return new HaltonSamplerProperties(m_film.Sampler as HaltonSampler);
                else if (m_film.Sampler is HammersleyFoldedSampler)
                    return new HammersleyFoldedSamplerProperties(m_film.Sampler as HammersleyFoldedSampler);
                else if (m_film.Sampler is HammersleySampler)
                    return new HammersleySamplerProperties(m_film.Sampler as HammersleySampler);
                else if (m_film.Sampler is SobolSampler)
                    return new SobolSamplerProperties(m_film.Sampler as SobolSampler);
                else
                    throw new NotImplementedException();
            }
        }

        [DisplayName("Maximum rays reflection count")]
        [Category(Categories.RENDER)]
        public int MaxRayDepth
        {
            get
            {
                return m_film.MaxRayDepth;
            }
            set
            {
                m_film.MaxRayDepth = value;
            }
        }
    }
}
